package run.iget.framework.common.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import run.iget.framework.common.enums.BaseResultEnum;
import run.iget.framework.common.exception.BusinessException;

/**
 * 代码千万行，注释第一行，注释不规范，迭代两行泪
 * ---------------类描述-----------------
 * 业务异常工具，快速判断参数进而抛出异常
 * ---------------类描述-----------------
 *
 * @author 大周
 * @date 2022/12/31 18:27
 */
public final class ExceptionThrowUtils {

    public static void ofTrue(Boolean obj) {
        ofTrue(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofTrue(Boolean obj, String msg) {
        ofTrue(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofTrue(Boolean obj, String code, String msg) {
        if (Objects.equals(Boolean.TRUE, obj)) {
            of(code, msg);
        }
    }

    public static void ofTrue(Boolean obj, BaseResultEnum resultEnum) {
        if (Objects.equals(Boolean.TRUE, obj)) {
            of(resultEnum);
        }
    }

    public static void ofAnyTrue(Boolean... obj) {
        ofAnyTrue(BaseResultEnum.ERROR_PARAM, obj);
    }

    public static void ofAnyTrue(String msg, Boolean... obj) {
        ofAnyTrue(BaseResultEnum.ERROR_PARAM.getCode(), msg, obj);
    }

    public static void ofAnyTrue(String code, String msg, Boolean... obj) {
        if (CheckUtils.isAnyTrue(obj)) {
            of(code, msg);
        }
    }

    public static void ofAnyTrue(BaseResultEnum resultEnum, Boolean... obj) {
        if (CheckUtils.isAnyTrue(obj)) {
            of(resultEnum);
        }
    }

    public static void ofAllTrue(Boolean... obj) {
        ofAllTrue(BaseResultEnum.ERROR_PARAM, obj);
    }

    public static void ofAllTrue(String msg, Boolean... obj) {
        ofAllTrue(BaseResultEnum.ERROR_PARAM.getCode(), msg, obj);
    }

    public static void ofAllTrue(String code, String msg, Boolean... obj) {
        if (CheckUtils.isAllTrue(obj)) {
            of(code, msg);
        }
    }

    public static void ofAllTrue(BaseResultEnum resultEnum, Boolean... obj) {
        if (CheckUtils.isAllTrue(obj)) {
            of(resultEnum);
        }
    }

    public static void ofNotTrue(Boolean obj) {
        ofNotTrue(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotTrue(Boolean obj, String msg) {
        ofNotTrue(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofNotTrue(Boolean obj, String code, String msg) {
        if (!Objects.equals(Boolean.TRUE, obj)) {
            of(code, msg);
        }
    }

    public static void ofNotTrue(Boolean obj, BaseResultEnum resultEnum) {
        if (!Objects.equals(Boolean.TRUE, obj)) {
            of(resultEnum);
        }
    }

    public static void ofFalse(Boolean obj) {
        ofFalse(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofFalse(Boolean obj, String msg) {
        ofFalse(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofFalse(Boolean obj, String code, String msg) {
        if (Objects.equals(Boolean.FALSE, obj)) {
            of(code, msg);
        }
    }

    public static void ofFalse(Boolean obj, BaseResultEnum resultEnum) {
        if (Objects.equals(Boolean.FALSE, obj)) {
            of(resultEnum);
        }
    }

    public static void ofNotFalse(Boolean obj) {
        ofNotFalse(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotFalse(Boolean obj, String msg) {
        ofNotFalse(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofNotFalse(Boolean obj, String code, String msg) {
        if (!Objects.equals(Boolean.FALSE, obj)) {
            of(code, msg);
        }
    }

    public static void ofNotFalse(Boolean obj, BaseResultEnum resultEnum) {
        if (!Objects.equals(Boolean.FALSE, obj)) {
            of(resultEnum);
        }
    }

    /**
     * 是null的时候，抛出 参数错误异常BusinessException
     *
     * @param obj 参数
     */
    public static void ofNull(Object obj) {
        ofNull(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNull(Object obj, String msg) {
        ofNull(obj, null, msg);
    }

    public static void ofNull(Object obj, String code, String msg) {
        ofTrue(Objects.isNull(obj), code, msg);
    }

    /**
     * 是null的时候，抛出异常BusinessException(resultEnum)
     *
     * @param obj        参数
     * @param resultEnum 异常参数
     */
    public static void ofNull(Object obj, BaseResultEnum resultEnum) {
        ofTrue(Objects.isNull(obj), resultEnum);
    }

    /**
     * 不是null的时候，抛出 参数错误异常BusinessException
     *
     * @param obj 参数
     */
    public static void ofNotNull(Object obj) {
        ofNull(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotNull(Object obj, String msg) {
        ofNull(obj, null, msg);
    }

    public static void ofNotNull(Object obj, String code, String msg) {
        ofTrue(Objects.nonNull(obj), code, msg);
    }

    /**
     * 不是null的时候，抛出异常BusinessException(resultEnum)
     *
     * @param obj        参数
     * @param resultEnum 异常参数
     */
    public static void ofNotNull(Object obj, BaseResultEnum resultEnum) {
        ofTrue(Objects.nonNull(obj), resultEnum);
    }

    public static void ofEmpty(Map obj) {
        ofEmpty(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofEmpty(Map obj, String msg) {
        ofEmpty(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofEmpty(Map obj, String code, String msg) {
        if (CollectionUtil.isEmpty(obj)) {
            of(code, msg);
        }
    }

    public static void ofEmpty(Map obj, BaseResultEnum resultEnum) {
        if (CollectionUtil.isEmpty(obj)) {
            of(resultEnum);
        }
    }

    public static void ofNotEmpty(Map obj) {
        ofNotEmpty(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotEmpty(Map obj, String msg) {
        ofNotEmpty(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofNotEmpty(Map obj, String code, String msg) {
        if (CollectionUtil.isNotEmpty(obj)) {
            of(code, msg);
        }
    }

    public static void ofNotEmpty(Map obj, BaseResultEnum resultEnum) {
        if (CollectionUtil.isNotEmpty(obj)) {
            of(resultEnum);
        }
    }

    public static void ofEmpty(Collection obj) {
        ofEmpty(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofEmpty(Collection obj, String msg) {
        ofEmpty(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofEmpty(Collection obj, String code, String msg) {
        if (CollectionUtil.isEmpty(obj)) {
            of(code, msg);
        }
    }

    public static void ofEmpty(Collection obj, BaseResultEnum resultEnum) {
        if (CollectionUtil.isEmpty(obj)) {
            of(resultEnum);
        }
    }

    public static void ofNotEmpty(Collection obj) {
        ofNotEmpty(obj, BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotEmpty(Collection obj, String msg) {
        ofNotEmpty(obj, BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofNotEmpty(Collection obj, String code, String msg) {
        if (CollectionUtil.isNotEmpty(obj)) {
            of(code, msg);
        }
    }

    public static void ofNotEmpty(Collection obj, BaseResultEnum resultEnum) {
        if (CollectionUtil.isNotEmpty(obj)) {
            of(resultEnum);
        }
    }

    /**
     * 抛出异常BusinessException(resultEnum)
     *
     * @param msg 异常消息
     */
    public static void of(String msg) {
        of(BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void of(String code, String msg) {
        of(code, msg, null);
    }

    public static void of(String code, String msg, Throwable cause) {
        if (StrUtil.isBlank(code)) {
            code = BaseResultEnum.ERROR_PARAM.getCode();
        }
        of(BaseResultEnum.of(code, msg), cause);
    }

    public static void of(String msg, Throwable cause) {
        of(BaseResultEnum.of(BaseResultEnum.ERROR_PARAM.getCode(), msg), cause);
    }

    public static void of(BaseResultEnum resultEnum) {
        throw new BusinessException(resultEnum, null);
    }

    public static void of(BaseResultEnum resultEnum, Throwable cause) {
        throw new BusinessException(resultEnum, cause);
    }

    /**
     * 获取异常信息
     * @param e  异常
     * @return    返回异常信息
     */
    public static String getExceptionMessage(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        e.printStackTrace(pw);

        // 关闭IO流
        IoUtil.close(pw);
        IoUtil.close(sw);

        return sw.toString();
    }

    public static void ofBlank(String obj) {
        ofTrue(StrUtil.isBlank(obj), BaseResultEnum.ERROR_PARAM);
    }

    public static void ofBlank(String obj, String msg) {
        ofTrue(StrUtil.isBlank(obj), BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofBlank(String obj, String code, String msg) {
        ofTrue(StrUtil.isBlank(obj), code, msg);
    }

    public static void ofBlank(String obj, BaseResultEnum resultEnum) {
        ofTrue(StrUtil.isBlank(obj), resultEnum);
    }

    public static void ofNotBlank(String obj) {
        ofTrue(StrUtil.isNotBlank(obj), BaseResultEnum.ERROR_PARAM);
    }

    public static void ofNotBlank(String obj, String msg) {
        ofTrue(StrUtil.isNotBlank(obj), BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofNotBlank(String obj, String code, String msg) {
        ofTrue(StrUtil.isNotBlank(obj), code, msg);
    }

    public static void ofNotBlank(String obj, BaseResultEnum resultEnum) {
        ofTrue(StrUtil.isNotBlank(obj), resultEnum);
    }

    public static void ofAnyBlank(String... obj) {
        ofTrue(StrUtil.hasBlank(obj), BaseResultEnum.ERROR_PARAM);
    }

    public static void ofAnyBlank(String msg, String... obj) {
        ofTrue(StrUtil.hasBlank(obj), BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofAnyBlank(String code, String msg, String... obj) {
        ofTrue(StrUtil.hasBlank(obj), code, msg);
    }

    public static void ofBlank(BaseResultEnum resultEnum, String... obj) {
        ofTrue(StrUtil.hasBlank(obj), resultEnum);
    }

    public static void ofAllBlank(String... obj) {
        ofTrue(StrUtil.isAllBlank(obj), BaseResultEnum.ERROR_PARAM);
    }

    public static void ofAllBlank(String msg, String... obj) {
        ofTrue(StrUtil.isAllBlank(obj), BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofAllBlank(String code, String msg, String... obj) {
        ofTrue(StrUtil.isAllBlank(obj), code, msg);
    }

    public static void ofAllBlank(BaseResultEnum resultEnum, String... obj) {
        ofTrue(StrUtil.isAllBlank(obj), resultEnum);
    }

    public static void ofAllNotBlank(String... obj) {
        ofTrue(StrUtil.isAllNotBlank(obj), BaseResultEnum.ERROR_PARAM);
    }

    public static void ofAllNotBlank(String msg, String... obj) {
        ofTrue(StrUtil.isAllNotBlank(obj), BaseResultEnum.ERROR_PARAM.getCode(), msg);
    }

    public static void ofAllNotBlank(String code, String msg, String... obj) {
        ofTrue(StrUtil.isAllNotBlank(obj), code, msg);
    }

    public static void ofAllNotBlank(BaseResultEnum resultEnum, String... obj) {
        ofTrue(StrUtil.isAllNotBlank(obj), resultEnum);
    }
}
